<?php
/**
 * Created by PhpStorm.
 * User: xiangfeng
 * Date: 2021/4/15
 * Time: 10:40 PM
 */

namespace app\api\extend\tools;


class SimpleModelConnectRedis
{
    private static $handler = null;
    private static $_instance = null;
    private static $options = REDIS_CONAFIG;

    private function __construct($options = [])
    {
        if (!extension_loaded('redis')) {
            throw new \BadFunctionCallException('not support: redis');      //判断是否有扩展
        }
        if (!empty($options)) {
            self::$options = array_merge(self::$options, $options);
        }
        $func = self::$options['persistent'] ? 'pconnect' : 'connect';     //长链接
        self::$handler = new \Redis();
        self::$handler->$func(self::$options['host'], self::$options['port'], self::$options['timeout']);

        if ('' != self::$options['password']) {
            self::$handler->auth(self::$options['password']);
        }

        if (0 != self::$options['select']) {
            self::$handler->select(self::$options['select']);
        }
    }

    /**
     * @return null 对象
     */
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 禁止外部克隆
     */
    public function __clone()
    {
        trigger_error('Clone is not allow!', E_USER_ERROR);
    }

    /**
     * 写入缓存
     * @param string $key 键名
     * @param string $value 键值
     * @param int $exprie 过期时间 0:永不过期
     * @return bool
     */


    public static function set($key, $value, $exprie = 0)
    {
        if ($exprie == 0) {
            $set = self::$handler->set($key, $value);
        } else {
            $set = self::$handler->setex($key, $exprie, $value);
        }
        return $set;
    }

    /**
     * 读取缓存
     * @param string $key 键值
     * @return mixed
     */
    public static function get($key)
    {
        $fun = is_array($key) ? 'Mget' : 'get';
        return self::$handler->{$fun}($key);
    }

    /**
     * 获取值长度
     * @param string $key
     * @return int
     */
    public static function lLen($key)
    {
        return self::$handler->lLen($key);
    }

    /**
     * 将一个或多个值插入到列表头部
     * @param $key
     * @param $value
     * @return int
     */
    public static function lPush($key, $value)
    {
        return self::$handler->lPush($key, $value);
    }

    /**
     * 将一个或多个值插入到列表头部
     * @param $key
     * @param $value
     * @return int
     */
    public static function rPush($key, $value)
    {
        return self::$handler->rPush($key, $value);
    }

    /**
     * 移出并获取列表的第一个元素
     * @param string $key
     * @return string
     */
    public static function lPop($key)
    {
        return self::$handler->lPop($key);
    }

    /**
     * 获取缓存 hash
     * @param $key
     * @return array
     */
    public function hGetAll($key)
    {
        return self::$handler->hGetAll($key);
    }

    /**
     * 设置缓存 hash
     * @param $key
     * @param $hashKeys
     * @param int $ttl
     * @return bool
     */
    public function hMSet($key, $hashKeys, $ttl = -1)
    {
        $data = self::$handler->hMSet($key, $hashKeys);
        if ($ttl > 0) {
            self::$handler->expire($key, $ttl);
        }
        return $data;
    }

    public function rPop($key)
    {
        return self::$handler->rPop($key);
    }

    /**
     * 删除指定key
     * @param $key
     * @return int
     */
    public function del($key)
    {
        return self::$handler->del($key);
    }

    public function setex($key, $ttl, $value)
    {
        return self::$handler->setex($key, $ttl, $value);
    }

    public function lRem($key, $value, $count)
    {
        return self::$handler->lRem($key, $value, $count);
    }

    public function lIndex($key, $index)
    {
        return self::$handler->lIndex($key, $index);
    }

    public function rpoplpush($srcKey, $dstKey)
    {
        return self::$handler->rpoplpush($srcKey, $dstKey);
    }

    public function expire($key, $time)
    {
        return self::$handler->expire($key, $time);
    }

    public function exists($key)
    {
        return self::$handler->exists($key);
    }

    public function incr($key, $ttl = -1)
    {
        $data = self::$handler->incr($key);
        if ($ttl > 0) {
            self::$handler->expire($key, $ttl);
        }
        return $data;
    }

    public function lRange($key, $start, $end)
    {
        return self::$handler->lRange($key, $start, $end);
    }

    public function setnx($key, $value)
    {
        return self::$handler->setnx($key, $value);
    }

    public function zAdd($key, $options, $score)
    {
        return self::$handler->zAdd($key, $options, $score);
    }

    public function zRange($key, $start, $end, $withscores = null)
    {
        if (empty($withscores)) {
            return self::$handler->zRange($key, $start, $end);
        } else {
            return self::$handler->zRange($key, $start, $end, $withscores);
        }

    }

    /**
     * 根据key前缀查所有 key
     * @param $key
     * @param int $count
     * @return array
     */
    public function key_scan_list($key, $count = 10)
    {
        try {
            if (empty($key)) {
                return [];
            }
            if ($count < 0) {
                $count = 0;
            }
            self::$handler->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
            $iterator = null;
            $total = [];
            while ($arrKeys = self::$handler->scan($iterator, $key, $count)) {
                $total = array_merge($total, $arrKeys);
            }
            return $total;
        } catch (\Exception $e) {
            return [];
        }
    }
}